﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing; 
 
using DevelopAssistant.Service.Properties;
using DevelopAssistant.Service;

namespace DevelopAssistant.Service.MSQLIntellisense
{
    public class SqlIntellisenseBox : IntellisenseBox
    {
        private const int MaxListLength = 16;
        private readonly ImageList images;

        bool fixedListViewWidth = true;

        IList<SqlIntellisenseBoxItem> IntellisenseList = null;

        public SqlIntellisenseBox()
        {
            this.images = new ImageList();

            this.images.Images.Add("Keyword", (Image)Resources.star);
            //this.images.Images.Add("Keyword", (Image)Resources.keyword);
            this.images.Images.Add("Table", (Image)Resources.table);
            this.images.Images.Add("View", (Image)Resources.view);
            this.images.Images.Add("Column", (Image)Resources.column);
            this.images.Images.Add("Proc", (Image)Resources.procs);
            this.images.Images.Add("Function", (Image)Resources.func);
            this.images.Images.Add("Variable", (Image)Resources.var);
            this.images.Images.Add("Snippet", (Image)Resources.snippets);
            this.ImageList = this.images;
            this.ItemHeight = this.Font.Height + 2;
        }

        public ImageList GetImageList()
        {
            return images;
        }

        public int GetImageIndex(SqlPromptType type)
        {
            switch (type)
            {
                case SqlPromptType.Procedure:
                    return 4;
                case SqlPromptType.UserFunction:
                case SqlPromptType.SysFunction:
                    return 5;
                case SqlPromptType.Variables:
                    return 6;
                case SqlPromptType.Table:
                    return 1;
                case SqlPromptType.Column:
                    return 3;
                case SqlPromptType.View:
                    return 2;
                case SqlPromptType.Snippet:
                    return 7;
                case SqlPromptType.Keyword:
                    return 0;                
                default:
                    return 0;
            }
        }

        public void FilterItems(string key, IList<SqlIntellisenseBoxItem> IntellisenseBoxItems)
        {
            int num = 0;
            this.Items.Clear();
            if (IntellisenseBoxItems == null)
                return;
            if (key.Contains("."))
                key = key.Substring(key.IndexOf('.') + 1);
            key = key.ToLower();           
            List<SqlIntellisenseBoxItem> _list = new List<SqlIntellisenseBoxItem>();
            foreach (SqlIntellisenseBoxItem intellisenseBoxItem in (IEnumerable<SqlIntellisenseBoxItem>)IntellisenseBoxItems)
            {
                if (intellisenseBoxItem.Text.ToLower().StartsWith(key))
                {
                    _list.Add(intellisenseBoxItem);
                    this.Items.Add((object)intellisenseBoxItem);
                    ++num;
                }
            }

            this.IntellisenseList = _list;
            this.AdjustSize();          
        }

        public void AdjustSize()
        {
            int height = this.ItemHeight * Math.Min(MaxListLength, (IntellisenseList.Count + 1));
            int width = this.ItemHeight * 10;
            if (!fixedListViewWidth)
            {
                width = GetListViewWidth(width, height);
            }
            this.Size =new Size(width, height);
        }

        int GetListViewWidth(int defaultWidth, int height)
        {
            float width = defaultWidth;
            using (Graphics graphics = this.CreateGraphics())
            {
                for (int i = 0; i < IntellisenseList.Count; ++i)
                {
                    float itemWidth = graphics.MeasureString(IntellisenseList[i].Text.ToString(), this.Font).Width;
                    if (itemWidth > width)
                    {
                        width = itemWidth;
                    }
                }
            }

            float totalItemsHeight = this.ItemHeight * IntellisenseList.Count;
            if (totalItemsHeight > height)
            {
                width += 12; // Compensate for scroll bar.
            }
            return (int)width;
        }

        private static SqlIntellisenseBox IntellisenseBox = null;
        private static object lockobject = new object();

        public static SqlIntellisenseBox Instance
        {
            get
            {
                if (IntellisenseBox == null)
                {
                    lock (lockobject)
                    {
                        if (IntellisenseBox == null)
                        {
                            IntellisenseBox = new SqlIntellisenseBox();
                        }
                    }
                }

                return IntellisenseBox;
            }
        }
    }
}
